package com.hunttown.mes.manage.service;

import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.common.cache.Cache;
import com.hunttown.mes.rpc.domain.TransportTableChineseEnglishDTO;
import com.hunttown.mes.rpc.domain.TransportTableChineseEnglishDetailDTO;
import com.hunttown.mes.rpc.domain.TransportUserDTO;
import com.hunttown.mes.rpc.domain.enums.user.UserLevelEnum;
import com.hunttown.mes.rpc.domain.enums.user.UserTypeEnum;
import com.hunttown.mes.rpc.domain.query.TransportTableChineseEnglishDetailDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.rpc.api.TransportUserRpcService;
import com.hunttown.mes.rpc.domain.query.TransportUserDTOQuery;
import com.hunttown.mes.common.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;

import java.math.BigDecimal;
import java.util.*;

/**
 * created by wangjunfu on 2019-05-18 20:14:43
 */
@Service
public class TransportUserManageService {

    private final static Logger logger = LoggerFactory.getLogger(TransportUserManageService.class);

    private final TransportUserRpcService rpcService;
    private final AnalysisManageManageService manageService;
    private final TransportUserCardManageService userCardService;
    private final TransportTableChineseEnglishManageService englishService;
    private final TransportTableChineseEnglishDetailManageService englishDetailService;
    private final AHelpManageService helpService;
    private final Cache jedisCache;

    @Autowired
    public TransportUserManageService(AnalysisManageManageService manageService, TransportUserRpcService rpcService, TransportUserCardManageService userCardService, TransportTableChineseEnglishManageService englishService, TransportTableChineseEnglishDetailManageService englishDetailService, AHelpManageService helpService, Cache jedisCache) {
        this.manageService = manageService;
        this.rpcService = rpcService;
        this.userCardService = userCardService;
        this.englishService = englishService;
        this.englishDetailService = englishDetailService;
        this.helpService = helpService;
        this.jedisCache = jedisCache;
    }

    // 新增
    public TransportUserDTO insert(TransportUserDTO objDTO) {
        objDTO.setTrueName(judgeTrueName(objDTO.getTrueName(), objDTO.getEntId()));
        return rpcService.insert(objDTO);
    }

    // 新增（简洁方法）
    public Integer insertSimple(String trueName, String mobile, Integer adminId) {
        TransportUserDTO obj = new TransportUserDTO();
        obj.setNickName(trueName);
        obj.setTrueName(trueName);
        obj.setMobile(mobile);
        obj.setUserType(UserTypeEnum.NORMAL.getKey());
        obj.setRelId(0);
        obj.setManageId(0);
        obj.setDriverId(0);
        obj.setStaffId(0);
        obj.setIsBindWxapp(0);
        obj.setIotRegionId(0);
        obj.setAdminId(adminId);
        return insertSimple(obj);
    }

    // 新增（导入浙商城用户使用）
    public Integer insertSimple(String trueName, String mobile, Integer iotRegion, String detailAddress) {
        TransportUserDTO obj = new TransportUserDTO();
        obj.setNickName(trueName);
        obj.setTrueName(trueName);
        obj.setMobile(mobile);
        obj.setUserType(UserTypeEnum.NORMAL.getKey());
        obj.setIotRegionId(iotRegion);
        obj.setDetailAddress(detailAddress);
        obj.setRelId(0);
        obj.setManageId(0);
        obj.setDriverId(0);
        obj.setStaffId(0);
        obj.setIsBindWxapp(0);
        obj.setAdminId(0);
        return insertSimple(obj);
    }

    // 新增（新增管理员、司机、会员时使用）
    public Integer insertSimple(String trueName, String mobile, Integer manageId, Integer driverId, Integer staffId, Integer adminId, Integer entId) {
        //如果手机号存在则不插入
        if (judgeMobile(mobile)) {
            return 0;
        }

        TransportUserDTO obj = new TransportUserDTO();
        if (entId != null && entId > 0) {
            obj.setEntId(entId);
        }
        obj.setNickName(trueName);
        obj.setTrueName(trueName);
        obj.setMobile(mobile);
        obj.setUserType(UserTypeEnum.NORMAL.getKey());
        obj.setRelId(0);
        obj.setManageId(manageId);
        obj.setDriverId(driverId);
        obj.setStaffId(staffId);
        obj.setIsBindWxapp(0);
        obj.setIotRegionId(0);
        obj.setAdminId(adminId);
        return insertSimple(obj);
    }

    // 参数越来越多，只能封装成类使用了。
    // TrueName：张三#1； 张三#2
    // NickName：张三；   张三    （真实姓名不可以重复，呢称可以重复。别问为什么，已经设计成这样了。）
    public Integer insertSimple(TransportUserDTO obj) {

        //先判断TrueName是否存在，如果存在，则使用：#+数字区分
        obj.setTrueName(judgeTrueName(obj.getTrueName(), obj.getEntId()));

        TransportUserDTO dto = new TransportUserDTO();
        dto.setEntId(obj.getEntId());

        //初始化导入数据时，有不存在手机号的情况
        if (StringUtils.isBlank(obj.getMobile())) {
            dto.setLogonName(ChineseToPinyinUtils.ToPinyin(obj.getTrueName().trim()));
        } else {
            dto.setLogonName(obj.getMobile());
        }

        //呢称为真实姓名，并去掉括号中的内容，只留姓名
        dto.setNickName(Html2TextUtils.filterBrackets(obj.getNickName()));

        //默认密码，我也不知道是什么，但是肯定是登录不了的。
        dto.setLogonPwd("98a9H77S24976HEd");
        dto.setUserType(obj.getUserType());
        dto.setUserLevel(UserLevelEnum.NORMAL.getKey());
        dto.setRelId(obj.getRelId());
        dto.setManageId(obj.getManageId());
        dto.setDriverId(obj.getDriverId());
        dto.setStaffId(obj.getStaffId());
        dto.setCompanyId(0);
        dto.setTrueName(obj.getTrueName());
        dto.setSex(-1);
        dto.setMarry(2);
        dto.setBirthday("1990-01-01");
        dto.setAge(0);
        dto.setStarSigns("");
        dto.setBloodtype("");
        dto.setBodySize("");
        dto.setEducation("");
        dto.setProfession("");
        dto.setCardType(0);
        dto.setCardNumber("");
        dto.setIsAuth(0);
        dto.setIotRegionId(obj.getIotRegionId() == null ? 0 : obj.getIotRegionId());
        dto.setCountry("");
        dto.setProvince(0);
        dto.setCity(0);
        dto.setArea(0);
        dto.setTown(0);
        dto.setVillage(0);
        dto.setDetailAddress(obj.getDetailAddress() == null ? "" : obj.getDetailAddress());
        dto.setZipCode("");
        dto.setFax("");
        dto.setEmail("");
        dto.setMobile(obj.getMobile());
        dto.setPhone("");
        dto.setQq("");
        dto.setAliww("");
        dto.setWeibo("");
        dto.setWeixin("");
        dto.setMsn("");
        dto.setHomePage("");
        dto.setPersonSign("");
        dto.setPhotoUrl("");
        dto.setPersonDes("");
        dto.setIsBindWxapp(0);
        dto.setAdminId(obj.getAdminId());
        dto.setCreateTime(new Date());
        dto.setUpdateTime(new Date());
        dto.setRegTime(new Date());
        dto.setRegIp("127.0.0.1");
        dto.setLastLoginTime(new Date());
        dto.setLastLoginIp("127.0.0.1");
        dto.setLoginTimes(0);
        dto.setDeleteFlag(0);

        //健康项目时新增
        dto.setRegisterType(0);
        dto.setIsCertification(0);
        dto.setExamineStatus(0);
        dto.setEnterpriseType(0);
        dto.setRegisterCapital(0);
        dto.setFoundDate(DateConvertUtils.strToDate("1990-01-01"));
        dto.setBranchId(0);
        dto.setMemberNumber(0);

        //浙商城特殊需求
        dto.setIsCanRecharge(1);
        dto.setLimitRecharge(BigDecimal.ZERO);
        dto.setIsCloseAfterCharge(0);

        dto = rpcService.insert(dto);

        if (dto != null && dto.getId() > 0) {
            //同时生成一张会员卡（默认充值卡）
            userCardService.insertSimple(dto.getId(), obj.getEntId());

            return dto.getId();
        } else {
            return 0;
        }
    }

    //region 每增加一名管理员、司机、员工都要向会员表中增加一名会员

    /**
     * 每增加一名管理员、司机、员工都要向会员表中增加一名会员
     * 1、没有直接插入（手机号查询）
     * 2、有则更新（相应id关联，更新手机号）
     *
     * @param from     来源：10管理员 20司机 30员工
     * @param relId    管理员表或司机表关联ID
     * @param mobile   手机号
     * @param trueName 真实姓名
     * @param adminId  操作人
     * @param entId    企业ID（设置多企业关联时用到，其它情况下不使用）
     */
    public void saveAUser(Integer from, Integer relId, String mobile, String trueName, Integer adminId, Integer entId) {
        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(trueName) || mobile.equals("--") || mobile.contains("00000")) {
            return;
        }

        mobile = mobile.trim();
        trueName = trueName.trim();

        Integer manageId = 0;
        Integer driverId = 0;
        Integer staffId = 0;

        //查询是否已经存在
        TransportUserDTOQuery fromQuery = new TransportUserDTOQuery();

        if (from == UserTypeEnum.MANAGE.getKey()) {
            fromQuery.setManageId(relId);
            manageId = relId;
        } else if (from == UserTypeEnum.DRIVER.getKey()) {
            fromQuery.setDriverId(relId);
            driverId = relId;
        } else {
            fromQuery.setStaffId(relId);
            staffId = relId;
        }

        fromQuery.setStopFlag(0);
        TransportUserDTO fromDTO = getByQuery(fromQuery);

        //[1].存在则更新（更新手机号、真实姓名。因为微信注册过的时候，真实姓名是呢称）
        if (fromDTO != null) {
            TransportUserDTO update = new TransportUserDTO();
            update.setId(fromDTO.getId());
            if (entId != null && entId > 0) {
                update.setEntId(entId);
            }
            update.setMobile(mobile);
            update.setTrueName(trueName);
            updateInfoById(update);
            return;
        }

        //[2].如果不存在，则通过手机号查询
        TransportUserDTO mobileDTO = getByMobile(mobile);

        //[3].存在当前用户，则更新（只更新relId， 有一种情况，就是前员工离职，后来的员工拿上他的手机号，如果离职员工未停用则会出现这种情况...停用并重新插入；这里只考虑会员先于管理录入系统的情况）
        if (mobileDTO != null) {
            TransportUserDTO update = new TransportUserDTO();
            update.setId(mobileDTO.getId());
            if (entId != null && entId > 0) {
                update.setEntId(entId);
            }

            if (from == UserTypeEnum.MANAGE.getKey()) {
                if (mobileDTO.getManageId() > 0) {
                    changeState(mobileDTO.getId(), 1, entId);
                    insertSimple(trueName, mobile, manageId, driverId, staffId, adminId, entId);
                    return;
                }
                update.setManageId(manageId);

            } else if (from == UserTypeEnum.DRIVER.getKey()) {
                if (mobileDTO.getDriverId() > 0) {
                    changeState(mobileDTO.getId(), 1, entId);
                    insertSimple(trueName, mobile, manageId, driverId, staffId, adminId, entId);
                    return;
                }
                update.setDriverId(driverId);

            } else {
                if (mobileDTO.getStaffId() > 0) {
                    changeState(mobileDTO.getId(), 1, entId);
                    insertSimple(trueName, mobile, manageId, driverId, staffId, adminId, entId);
                    return;
                }
                update.setStaffId(staffId);
            }

            update.setTrueName(trueName);
            updateInfoById(update);
            return;
        }

        insertSimple(trueName, mobile, manageId, driverId, staffId, adminId, entId);
    }
    //endregion

    //判断nickname是否存在
    private String judgeTrueName(String truename, Integer entId) {
        if (StringUtils.isBlank(truename)) {
            return truename;
        }

        truename = truename.trim();

        Object value = ScriptFilterUtils.judgeXss(truename);
        truename = value.toString().trim();

        TransportUserDTOQuery nickQuery = new TransportUserDTOQuery();
        if (entId != null && entId > 0) {
            nickQuery.setEntId(entId);
        }
        nickQuery.setTrueName(truename);
        TransportUserDTO dto = rpcService.selectObjByQuery(nickQuery);

        if (dto == null) {
            return truename;

        } else {
            TransportUserDTOQuery likeQuery = new TransportUserDTOQuery();
            likeQuery.setLikeName(truename);
            likeQuery.setOrderBy("order by id desc");
            TransportUserDTO lastDTO = rpcService.selectObjByQuery(likeQuery);

            if (lastDTO.getTrueName().equals(truename)) {
                return truename + "#1";
            } else {
                String[] param = lastDTO.getTrueName().split("#");
                if (param.length == 2) {
                    int sign = Integer.parseInt(param[1]);
                    return truename + "#" + (sign + 1);
                } else {
                    return truename + "#1";
                }
            }
        }
    }

    //判断手机号是否存在
    private Boolean judgeMobile(String mobile) {
        TransportUserDTO dto = getByMobile(mobile);
        return dto != null;
    }

    // 通过ID修改
    public Boolean updateInfoById(TransportUserDTO objDTO) {
        Boolean isNext = rpcService.updateInfoById(objDTO);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(objDTO.getId());
        }
        return isNext;
    }

    // 通过Query修改
    public Boolean updateInfoByQuery(TransportUserDTOQuery objDTOQuery) {
        Boolean isNext = rpcService.updateInfoByQuery(objDTOQuery);

        //单体刷新
        if (isNext && objDTOQuery.getW_id() != null) {
            refreshCacheById(objDTOQuery.getW_id());
        }

        //批量刷新缓存
        if (isNext && objDTOQuery.getIds() != null) {
            List<Integer> list = new ArrayList<>();
            try {
                list = (List<Integer>) objDTOQuery.getIds();
            } catch (Exception e) {
                e.printStackTrace();
            }
            refreshCacheByIdList(list);
        }
        return isNext;
    }

    // 通过ID删除
    public Boolean delete(Integer id) {
        Boolean isNext = rpcService.deleteById(id);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(id);
        }
        return isNext;
    }

    // 批量删除
    public Boolean deleteForBatch(String clearIds) {

        //处理 “,5,6,7,” 为List
        List<Integer> idList = FormatUtils.commaToList_Integer(clearIds);

        if (idList.size() == 0) {
            return false;
        }

        TransportUserDTOQuery query = new TransportUserDTOQuery();
        query.setDeleteFlag(1);
        query.setIds(idList);

        Boolean isNext = rpcService.updateInfoByQuery(query);
        if (isNext) {
            // 刷新缓存
            refreshCacheByIdList(idList);
        }

        return isNext;
    }

    // 通过ID获取
    public TransportUserDTO getById(Integer id) {
        if (id == null || id <= 0) {
            return null;
        }
        return rpcService.selectById(id);
    }

    // 根据手机号获取会员信息
    public TransportUserDTO getByMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return null;
        }

        TransportUserDTOQuery query = new TransportUserDTOQuery();
        query.setMobile(mobile.trim());
        query.setStopFlag(0);
        return getByQuery(query);
    }

    // 根据第三方ID（管理员、司机、员工ID）获取会员信息
    public TransportUserDTO getByRelId(Integer relId, Integer userType) {
        if (relId == null || relId <= 0) {
            return null;
        }

        TransportUserDTOQuery query = new TransportUserDTOQuery();
        if (userType == UserTypeEnum.MANAGE.getKey()) {
            query.setManageId(relId);
        } else if (userType == UserTypeEnum.DRIVER.getKey()) {
            query.setDriverId(relId);
        } else {
            query.setStaffId(relId);
        }
        return getByQuery(query);
    }

    // 根据管理员ID获取会员ID
    public Integer getUserIdByAdminId(Integer adminId) {
        TransportUserDTO dto = getByRelId(adminId, UserTypeEnum.MANAGE.getKey());
        return dto == null ? 0 : dto.getId();
    }

    // 通过Query获取
    public TransportUserDTO getByQuery(TransportUserDTOQuery objDTOQuery) {
        return rpcService.selectObjByQuery(objDTOQuery);
    }

    // 获取分页列表
    public Page<TransportUserDTO> getForPage(TransportUserDTOQuery objDTOQuery) {
        return rpcService.getListForPage(objDTOQuery);
    }

    // 只获取管理员、司机的会员列表
    public Page<TransportUserDTO> getManageDriverUser(String userName, String mobile) {
        TransportUserDTOQuery userQuery = new TransportUserDTOQuery();
        if (StringUtils.isNotBlank(userName)) {
            userQuery.setLikeName(userName.trim());
        }
        if (StringUtils.isNotBlank(mobile)) {
            userQuery.setMobileLike(mobile.trim());
        }
        userQuery.setManageOrDriver(1);
        userQuery.setStopFlag(0);
        userQuery.setPageSize(1000);
        return getForPage(userQuery);
    }

    // 改变某条记录的使用状态
    public Boolean changeState(Integer id, Integer state, Integer entId) {
        TransportUserDTO obj = new TransportUserDTO();
        obj.setStopFlag(state);
        if (entId != null && entId > 0) {
            obj.setEntId(entId);
        }
        obj.setId(id);
        return updateInfoById(obj);
    }

    //region 从缓存中获取数据

    /**
     * 先从缓存中获取数据
     * 如果缓存为空，从数据库中获取，并将获取的数据添加到缓存。
     *
     * @param id id
     * @return obj
     */
    public TransportUserDTO getFromCacheId(Integer id) {
        if (id == null || id <= 0) {
            return null;
        }

        TransportUserDTO obj = jedisCache.oget(KeyConstants.USER_INFO_KEY_ID + id, TransportUserDTO.class);
        if (obj == null) {
            obj = getById(id);
            if (obj != null) {
                jedisCache.oset(KeyConstants.USER_INFO_KEY_ID + id, obj);
            }
        }

        return obj;
    }

    /**
     * 从缓存中获取会员姓名
     * 如果没有再从数据库中获取
     *
     * @param userId 会员id
     * @return name
     */
    public String getTrueName(Integer userId) {
        TransportUserDTO userDTO = getFromCacheId(userId);
        return userDTO == null ? "--" : userDTO.getTrueName();
    }

    /**
     * 通过姓名获取会员信息
     * 先从缓存中获取，如果没有再从数据库中获取
     *
     * @param trueName 会员姓名
     * @return obj
     */
    public TransportUserDTO getByTrueName(String trueName) {
        if (StringUtils.isBlank(trueName)) {
            return null;
        }

        String key = ChineseToPinyinUtils.ToPinyin(trueName.trim());

        //不同企业可能有相同的用户，所以KEY可能相同
        key += "_" + helpService.getEnterpriseId();

        TransportUserDTO obj = jedisCache.oget(KeyConstants.USER_INFO_KEY_TRUENAME + key, TransportUserDTO.class);
        if (obj == null) {
            TransportUserDTOQuery query = new TransportUserDTOQuery();
            query.setTrueName(trueName.trim());
            query.setDeleteFlag(0);
            obj = getByQuery(query);

            if (obj != null) {
                jedisCache.oset(KeyConstants.USER_INFO_KEY_TRUENAME + key, obj);
            }
        }

        return obj;
    }

    //endregion

    //region 刷新缓存

    /**
     * 刷用户缓存
     *
     * @param id 会员id
     */
    public void refreshCacheById(Integer id) {
        if (id == null || id <= 0) {
            return;
        }

        TransportUserDTO obj = getById(id);
        if (obj != null) {
            jedisCache.delete(KeyConstants.USER_INFO_KEY_ID + id);
            jedisCache.delete(KeyConstants.USER_INFO_KEY_TRUENAME + ChineseToPinyinUtils.ToPinyin(obj.getTrueName()) + "_" + obj.getEntId());
            jedisCache.delete(KeyConstants.USER_INFO_KEY_MOBILE + ChineseToPinyinUtils.ToPinyin(obj.getMobile()) + "_" + obj.getEntId());
        }
    }

    /**
     * 刷用户缓存(批量)
     *
     * @param idList list
     */
    public void refreshCacheByIdList(List<Integer> idList) {
        if (idList == null || idList.size() == 0) {
            return;
        }

        for (Integer id : idList) {
            refreshCacheById(Integer.valueOf(id.toString()));
        }
    }
    //endregion

    //region 数据查看

    /**
     * 组装实体信息为前台可展示的格式
     * 可做定制化的配置
     * 存放位置：各业务的Service中
     *
     * @param model     Sevelet Model
     * @param tableName 数据库表名
     * @param obj       对象
     * @return model
     */
    public Model assembleObjInfo(Model model, String tableName, TransportUserDTO obj) {

        // 结果集返回一个map
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

        // 显示标题
        String showTitle = obj == null ? "详情" : obj.getTrueName();

        // 获取数据库中英文对照表主表信息
        TransportTableChineseEnglishDTO englishDTO = englishService.getByTableName(tableName);

        if (obj == null || englishDTO == null) {
            map.put("没有查询到数据！", "");
        } else {
            Map<String, Object> origin_map = GeneralUtils.ergodicModel(FastJsonUtils.toJSONString(obj), TransportUserDTO.class);

            if (origin_map != null) {
                // 根据表ID（tableId）获取表字段信息
                TransportTableChineseEnglishDetailDTOQuery query = new TransportTableChineseEnglishDetailDTOQuery();
                query.setTableId(englishDTO.getId());
                query.setDeleteFlag(0);
                query.setPageSize(1000);
                Page<TransportTableChineseEnglishDetailDTO> detailPage = englishDetailService.getForPage(query);

                if (detailPage != null && detailPage.getItems().size() > 0) {
                    Object value;
                    String newfield;
                    for (TransportTableChineseEnglishDetailDTO item : detailPage.getItems()) {
                        if (item.getFrontShow() == 1) {
                            newfield = GeneralUtils.standardFields(item.getFieldName());
                            value = origin_map.get(newfield);
                            if (item.getFieldType().toUpperCase().equals("TIMESTAMP")) {
                                map.put(item.getFieldNameCn(), DateConvertUtils.cstToShortStrDate(value.toString()));
                            } else {

                                if (value == null || StringUtils.isBlank(value.toString())) {
                                    map.put(item.getFieldNameCn(), "--");
                                    continue;
                                }

                                //region 开始个性化设置
                                if (newfield.equals("logonPwd")) {  //密码隐藏
                                    value = "--";
                                }
                                if (newfield.equals("adminId")) {   //创建人
                                    value = manageService.getNickNameFromCache(Integer.valueOf(value.toString()));
                                }
                                if (newfield.equals("stopFlag")) { //启停用状态
                                    value = value.equals(0) ? "启用" : "停用";
                                }
                                //endregion

                                map.put(item.getFieldNameCn(), value.toString());
                            }
                        }
                    }
                }
            }
        }

        model.addAttribute("showTitle", showTitle);
        model.addAttribute("showResult", map);

        return model;
    }

    //endregion

    //region 模糊搜索会员
    public List<Map<String, String>> getSimilarUser(String similar, Integer userType) {
        return rpcService.selectSimilarUser(similar, userType);
    }
    //endregion

    //以map的形式返回数据
    public List<Map<String, String>> getMapDataByQuery(TransportUserDTOQuery objDTOQuery, String element) {
        return rpcService.getMapDataByQuery(objDTOQuery, element);
    }

}